namespace SubSonic
{
    using SubSonic.Utilities;
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Text.RegularExpressions;

    public class StoredProcedure
    {
        private QueryCommand _cmd;
        private ParameterCollection _parameters;
        private readonly DataProvider _provider;
        private int commandTimeout;
        private readonly string displayName;
        private readonly string name;
        public List<object> OutputValues;
        private readonly string tableName;

        public StoredProcedure(string spName) : this(spName, DataService.Provider)
        {
        }

        public StoredProcedure(string spName, DataProvider provider)
        {
            this._parameters = new ParameterCollection();
            this.commandTimeout = 60;
            this.name = spName;
            this.tableName = provider.SPClassName;
            this._cmd = new QueryCommand(spName, provider.Name);
            this._cmd.CommandType = CommandType.StoredProcedure;
            this._provider = provider;
            this._cmd.ProviderName = this._provider.Name;
            this._cmd.CommandTimeout = this.commandTimeout;
            string str = spName;
            if (provider.ExtractClassNameFromSPName)
            {
                Match match = Regex.Match(spName, "(?<=^UNDERSCORE).*?(?=UNDERSCORE)");
                if (match.Success)
                {
                    this.tableName = match.Value;
                    str = Regex.Replace(spName, "^UNDERSCORE.*?UNDERSCORE", string.Empty);
                }
                else
                {
                    Match match2 = Regex.Match(spName, "(?<=^_).*?(?=_)");
                    if (match2.Success)
                    {
                        this.tableName = match2.Value;
                        str = Regex.Replace(spName, "^_.*?_", string.Empty);
                    }
                }
            }
            this.displayName = TransformSPName(str, provider);
            this.OutputValues = new List<object>();
        }

        public int Execute()
        {
            int num = DataService.ExecuteQuery(this._cmd);
            this.OutputValues = this._cmd.OutputValues;
            return num;
        }

        public object ExecuteScalar()
        {
            object obj2 = DataService.ExecuteScalar(this._cmd);
            this.OutputValues = this._cmd.OutputValues;
            return obj2;
        }

        public DataSet GetDataSet()
        {
            return this.GetDataSet<DataSet>();
        }

        public T GetDataSet<T>() where T: DataSet, new()
        {
            T dataSet = DataService.GetDataSet<T>(this._cmd);
            this.OutputValues = this._cmd.OutputValues;
            return dataSet;
        }

        public static DataSet GetDataSet(string spAndParams)
        {
            return GetDataSet(spAndParams, string.Empty);
        }

        public static DataSet GetDataSet(string spAndParams, string providerName)
        {
            QueryCommand cmd = new QueryCommand("EXEC " + spAndParams, providerName);
            cmd.CommandType = CommandType.Text;
            cmd.ProviderName = providerName;
            return DataService.GetDataSet(cmd);
        }

        public IDataReader GetReader()
        {
            IDataReader reader = DataService.GetReader(this._cmd);
            this.OutputValues = this._cmd.OutputValues;
            return reader;
        }

        public static IDataReader GetReader(string spAndParams)
        {
            return GetReader(spAndParams, "");
        }

        public static IDataReader GetReader(string spAndParams, string providerName)
        {
            QueryCommand cmd = new QueryCommand("EXEC " + spAndParams, providerName);
            cmd.CommandType = CommandType.Text;
            cmd.ProviderName = providerName;
            return DataService.GetReader(cmd);
        }

        private static string TransformSPName(string spName, DataProvider provider)
        {
            if (string.IsNullOrEmpty(spName))
            {
                return string.Empty;
            }
            string inputText = spName;
            inputText = Utility.GetProperName(Utility.StripText(Utility.RegexTransform(inputText, provider), provider.StripSPText), provider);
            inputText = Utility.IsStringNumeric(inputText) ? ("_" + inputText) : inputText;
            return Utility.KeyWordCheck(Utility.StripNonAlphaNumeric(inputText).Trim(), string.Empty, provider);
        }

        public QueryCommand Command
        {
            get
            {
                return this._cmd;
            }
            set
            {
                this._cmd = value;
            }
        }

        public int CommandTimeout
        {
            get
            {
                return this.commandTimeout;
            }
            set
            {
                this.commandTimeout = value;
            }
        }

        public string DisplayName
        {
            get
            {
                return this.displayName;
            }
        }

        public string Name
        {
            get
            {
                return this.name;
            }
        }

        public ParameterCollection Parameters
        {
            get
            {
                return this._parameters;
            }
            set
            {
                this._parameters = value;
            }
        }

        public DataProvider Provider
        {
            get
            {
                return this._provider;
            }
        }

        public string TableName
        {
            get
            {
                return this.tableName;
            }
        }

        public class Parameter
        {
            private DbType dbType;
            private string displayName;
            private ParameterDirection mode = ParameterDirection.Input;
            private string name;
            private string queryParameter;

            public DbType DBType
            {
                get
                {
                    return this.dbType;
                }
                set
                {
                    this.dbType = value;
                }
            }

            public string DisplayName
            {
                get
                {
                    return this.displayName;
                }
                set
                {
                    this.displayName = value;
                }
            }

            public ParameterDirection Mode
            {
                get
                {
                    return this.mode;
                }
                set
                {
                    this.mode = value;
                }
            }

            public string Name
            {
                get
                {
                    return this.name;
                }
                set
                {
                    this.name = value;
                }
            }

            public string QueryParameter
            {
                get
                {
                    return this.queryParameter;
                }
                set
                {
                    this.queryParameter = value;
                }
            }
        }

        public class ParameterCollection : List<StoredProcedure.Parameter>
        {
        }
    }
}

